/*
 * Copyright (C) 2018 xuexiangjys(xuexiangjys@163.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.xuexiang.xui_lib.component.popupwindow.bar;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Image;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.Text;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;

import com.xuexiang.xui_lib.ResourceTable;
import com.xuexiang.xui_lib.util.TextUtils;


/**
 * 顶部和底部信息消息显示条
 *
 * @author xuexiang
 * @since 2018/12/19 上午9:20
 */
final class Cookie extends DirectionalLayout implements ComponentContainer.ArrangeListener {

    /**
     * 默认持续时间（ms）
     */
    public static final long DEFAULT_COOKIE_DURATION = 2000;

    private AnimatorProperty mSlideOutAnimation;

    private DirectionalLayout mLayoutCookie;
    private Text mTvTitle;
    private Text mTvMessage;
    private Image mIvIcon;
    private Text mBtnAction;
    private Image mBtnActionWithIcon;
    private long mDuration = DEFAULT_COOKIE_DURATION;
    private int mGravity = LayoutAlignment.BOTTOM;

    public Cookie(final Context context) {
        this(context, null);
    }

    public Cookie(final Context context, final AttrSet attrs) {
        this(context, attrs, 0);
    }

    public Cookie(final Context context, final AttrSet attrs,
                  final int defStyleAttr) {
        super(context, attrs, String.valueOf(defStyleAttr));
        initViews(context);
    }

    public int getLayoutGravity() {
        return mGravity;
    }

    private void initViews(Context context) {
        LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_xui_layout_cookie, this, true);
        mLayoutCookie = (DirectionalLayout) findComponentById(ResourceTable.Id_cookie);
        mTvTitle = (Text) findComponentById(ResourceTable.Id_tv_title);
        mTvMessage = (Text) findComponentById(ResourceTable.Id_tv_message);
        mIvIcon = (Image) findComponentById(ResourceTable.Id_iv_icon);
        mBtnAction = (Text) findComponentById(ResourceTable.Id_btn_action);
        mBtnActionWithIcon = (Image) findComponentById(ResourceTable.Id_btn_action_with_icon);
        initDefaultStyle(context);
    }

    /**
     * Init the default text color or background color. You can change the default style by set the
     * Theme's attributes.
     *
     * <pre>
     *  <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
     *          <item name="cookieTitleColor">@color/default_title_color</item>
     *          <item name="cookieMessageColor">@color/default_message_color</item>
     *          <item name="cookieActionColor">@color/default_action_color</item>
     *          <item name="cookieBackgroundColor">@color/default_bg_color</item>
     *  </style>
     * </pre>
     *
     * @param context
     */
    private void initDefaultStyle(Context context) {
        mTvTitle.setTextColor(Color.WHITE);
        mTvMessage.setTextColor(Color.WHITE);
        mBtnAction.setTextColor(Color.WHITE);
    }

    public void setParams(final CookieBar.Params params) {
        if (params != null) {
            mDuration = params.duration;
            mGravity = params.layoutGravity;

            //Icon
            if (params.iconResId != 0) {
                mIvIcon.setVisibility(VISIBLE);
                mIvIcon.setPixelMap(params.iconResId);
            }

            //Title
            if (!TextUtils.isEmpty(params.title)) {
                mTvTitle.setVisibility(VISIBLE);
                mTvTitle.setText(params.title);
                if (params.titleColor != 0) {
                    mTvTitle.setTextColor(new Color(params.titleColor));
                }
            }

            //Message
            if (!TextUtils.isEmpty(params.message)) {
                mTvMessage.setVisibility(VISIBLE);
                mTvMessage.setText(params.message);
                if (params.messageColor != 0) {
                    mTvMessage.setTextColor(new Color(params.messageColor));
                }

                if (TextUtils.isEmpty(params.title)) {
                    LayoutConfig layoutParams = (LayoutConfig) mTvMessage
                        .getLayoutConfig();
                    layoutParams.setMarginTop(0);
                }
            }

            //Action
            if ((!TextUtils.isEmpty(params.action) || params.actionIcon != 0)
                && params.onActionClickListener != null) {
                mBtnAction.setVisibility(VISIBLE);
                mBtnAction.setText(params.action);
                mBtnAction.setClickedListener(new ClickedListener() {
                    @Override
                    public void onClick(Component component) {
                        params.onActionClickListener.onClick(component);
                        dismiss();
                    }
                });

                //Action Color
                if (params.actionColor != 0) {
                    mBtnAction.setTextColor(new Color(params.actionColor));
                }
            }

            if (params.actionIcon != 0 && params.onActionClickListener != null) {
                mBtnAction.setVisibility(HIDE);
                mBtnActionWithIcon.setVisibility(VISIBLE);
                mBtnActionWithIcon.setPixelMap(params.actionIcon);
                mBtnActionWithIcon.setClickedListener(new ClickedListener() {
                    @Override
                    public void onClick(Component component) {
                        params.onActionClickListener.onClick(component);
                        dismiss();
                    }
                });
            }

            //Background
            if (params.backgroundColor != 0) {
                ShapeElement shapeElement = new ShapeElement();
                shapeElement.setRgbColor(RgbColor.fromArgbInt(params.backgroundColor));
                mLayoutCookie.setBackground(shapeElement);
            }

            int padding = 15;
            mLayoutCookie.setPadding(40, padding, padding, padding);
        }
    }


    @Override
    public boolean onArrange(int left, int top, int width, int height) {
        if (mGravity == LayoutAlignment.TOP) {
            this.onArrange(left, top, width, mLayoutCookie.getEstimatedHeight());
        } else {
            this.onArrange(left, top, width, height);
        }
        return false;
    }

    public void createInAnim() {
        AnimatorProperty animator = mGravity == LayoutAlignment.BOTTOM ? createAniminBOTTOM() : createAniminTop();
        animator.setTarget(Cookie.this);
        animator.setStateChangedListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {

            }

            @Override
            public void onStop(Animator animator) {

            }

            @Override
            public void onCancel(Animator animator) {

            }

            @Override
            public void onEnd(Animator animator) {
                if (mDuration < 0) {
                    return;
                }
                new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
                    @Override
                    public void run() {
                        dismiss();
                    }
                }, mDuration);
            }

            @Override
            public void onPause(Animator animator) {

            }

            @Override
            public void onResume(Animator animator) {

            }
        }).start();
    }

    public void createOutAnim() {
        mSlideOutAnimation = mGravity == LayoutAlignment.BOTTOM ? createAnimOutBOTTOM() : createAnimOutTop();
        mSlideOutAnimation.setTarget(Cookie.this);
        mSlideOutAnimation.setStateChangedListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {

            }

            @Override
            public void onStop(Animator animator) {

            }

            @Override
            public void onCancel(Animator animator) {

            }

            @Override
            public void onEnd(Animator animator) {
                destroy();
            }

            @Override
            public void onPause(Animator animator) {

            }

            @Override
            public void onResume(Animator animator) {

            }
        }).start();
    }

    /**
     * 消失
     */
    public void dismiss() {
        createOutAnim();
    }

    /**
     * 销毁
     */
    private void destroy() {
        new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
            @Override
            public void run() {
                ComponentContainer component = (ComponentContainer) getComponentParent();
                if (component != null) {
                    ((ComponentContainer) component).removeComponent(Cookie.this);

                }
            }
        }, 200);
    }

    private AnimatorProperty createAniminTop() {
        AnimatorProperty animator = new AnimatorProperty();
        animator.moveFromY(-100).moveToY(0).alphaFrom(0).alpha(1).setDuration(700);
        return animator;
    }

    private AnimatorProperty createAniminBOTTOM() {
        AnimatorProperty animator = new AnimatorProperty();
        int height = DisplayManager.getInstance().getDefaultDisplay(getContext()).get().getAttributes().height;
        int cokeieBarh = height - mLayoutCookie.getHeight();
        animator.moveFromY(height).moveToY(cokeieBarh).alphaFrom(0).alpha(1).setDuration(200);
        return animator;
    }

    private AnimatorProperty createAnimOutTop() {
        AnimatorProperty animator = new AnimatorProperty();
        animator.moveFromY(0).moveToY(-300).alphaFrom(1).alpha(0).setDuration(400);
        return animator;
    }

    private AnimatorProperty createAnimOutBOTTOM() {
        AnimatorProperty animator = new AnimatorProperty();
        int height = DisplayManager.getInstance().getDefaultDisplay(getContext()).get().getAttributes().height;
        int cokeieBarh = height - mLayoutCookie.getHeight();
        animator.moveFromY(cokeieBarh).moveToY(height).alphaFrom(1).alpha(0).setDuration(400);
        return animator;
    }
}
